package com.rainbow.support.half.message.handler.producer;

import com.rainbow.common.core.toolkit.ContextHolder;
import com.rainbow.common.core.toolkit.SpringBeanUtil;
import com.rainbow.support.half.message.entity.HalfMessagePayload;
import com.rainbow.support.half.message.handler.BaseHalfMsgHandler;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.lang.NonNull;
import java.util.Date;
import java.util.Objects;

/**
 * rocketMq半事务统一处理
 * 生产者统一处理接口规范
 * @author 傅为地
 */
public interface HalfMsgProducerHandler extends BaseHalfMsgHandler {

    /**
     * Mq事务监听器,本地生产者处理接口
     * 不推荐采用此方法处理生产者,消息体内日期格式可能存在问题
     * 推荐采用{@link #process(HalfMessagePayload producer)}
     * @param message 生产者参数
     * @return 本地事务处理结果
     */
    @Deprecated
    boolean process(@NonNull String message);

    /**
     * Mq事务监听器,本地生产者处理接口
     *
     * @param producer 生产者参数
     * @return 本地事务处理结果
     */
    boolean process(@NonNull HalfMessagePayload producer);

    /**
     * 本地业务处理,开启事务处理
     *
     * @param producer 生产者参数
     * @param message 源消息信息
     * @return 本地事务处理结果
     */
    boolean serviceProcess(@NonNull HalfMessagePayload producer, @NonNull String message);

    /**
     * TODO 本地业务处理之前的准备参数,需要业务自己实现
     * 本地业务逻辑处理之前,需要查询好需要处理的参数信息
     * 本地事务处理时,直接处理业务逻辑,解决大事务的问题
     *
     * @param producer 生产者参数
     */
    default void prepareParams(@NonNull HalfMessagePayload producer) {
    }

    /**
     * 本地事务处理后,存储生产者事务日志
     *
     * @param producer 生产者参数
     * @param message  源消息信息
     * @return 本地事务存储结果
     */
    default boolean saveProducerLog(@NonNull HalfMessagePayload producer, @NonNull String message) {
        String insertSql = "INSERT INTO rocket_mq_producer_log(branch_id,global_id,origin_body,remark,category,endpoint,chainpath,expandtag,reservetag,create_time,creator,logic_delete) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";
        Integer total = Objects.requireNonNull(SpringBeanUtil.getBean(JdbcTemplate.class)).update(insertSql, producer.getBranchId(), producer.getGlobalId(), message, producer.getRemark(), producer.getCategory(), producer.getEndpoint(), producer.getChainpath(), producer.getExpandtag(), producer.getReservetag(), new Date(), ContextHolder.getUserId(), false);
        return ObjectUtils.isNotEmpty(total) && total > 0;
    }

}
